<template>
  <!-- 模型弹窗：根据editModel渲染，0 上传模型；1 编辑模型；2 更新模型版本；3 历史版本；4 组合模型 -->
  <dialog-form
    ref="dialogForm"
    :visible.sync="dialogVisible"
    :edit-model="editModel === 3 ? 'V' : 'E'"
    :api="editModel === 1 || editModel === 2 ? getBimModelDetail : null"
    :form="form"
    :forms.sync="form"
    :header-title="['上传模型', '编辑模型', '更新模型', '模型历史版本', '组合模型'][editModel]"
    :width="1000"
    :isEmit="false"
    :rules="rules"
    :form-list="formList"
    @confirm="submitForm"
    @beforeInit="beforeInit"
  >
    <template
      v-if="editModel === 3&&dialogVisible"
      #formHeader
    >
      <bTable
        ref="tableHistory"
        :columns="columnsHistory"
        :pageKeys="['pageNum', 'pageSize', 'total']"
        :request="loadDataHistory"
        row-key="id"
      >
        <!-- 操作 -->
        <template
          slot="actions"
          slot-scope="text, record, index"
        >
          <a
            class="base-btn"
            @click.stop="handleOpen([{ modelId: record.modelFileId, version: record.modelFileVersion, modelTitle: form.modelName }])"
          >查看</a>
          <a-divider type="vertical" />
          <a
            v-if="$refs.tableHistory.totalSize > 1 && index!==0"
            class="base-btn del_btn"
            @click.stop="handleRemove(record)"
          >删除</a>
          <a
            v-if="index===0&&!downloading"
            class="base-btn"
            @click.stop="handleDownload(record)"
          >下载</a>
          <a-spin :spinning="downloading" v-if="index===0">
            <a-icon
              slot="indicator"
              type="loading"
              style="font-size: 14px"
              spin
            />
          </a-spin>
        </template>
      </bTable>
    </template>
    <!-- 选择模型 -->
    <template #fileList>
      <a-upload
        name="fileList"
        :disabled="editModel === 1"
        :multiple="false"
        :fileList="form.fileList"
        :beforeUpload="beforeUpload"
        @change="handleUploadChanged"
      >
        <a-button v-if="editModel !== 1">
          <a-icon type="upload" />点击选择
        </a-button>
      </a-upload>
      <div v-if="editModel !== 1">仅支持.zip格式</div>
    </template>
  </dialog-form>
</template>

<script>
import { getPageTypesLabel } from '@/api/bimIntegrate/bimResource.js'
import Selector from '@/components/Select/Selector'
import { addBimModel, editBimModel, getBimModelDetail, getBimModelVersion, addBimModelVersion, deleteBimModelVersion, addBimPortfolioModel } from '@/api/bimIntegrate/bimModel'
import DialogForm from '@/components/DialogForm' // 弹窗
import { uploadModel, updateModel, downloadModel } from '@/api/bimIntegrate'

const columnsHistory = [
  {
    title: '版本信息',
    dataIndex: 'modelVersion'
  },
  {
    title: '版本说明',
    dataIndex: 'versionExplain'
  },
  {
    title: '上传人',
    dataIndex: 'creatorUserName'
  },
  {
    title: '上传时间',
    dataIndex: 'createTime'
  },
  {
    title: '文件大小',
    dataIndex: 'modelSize',
    customRender(e) {
      return e ? e + 'M' : '无'
    }
  },
  {
    title: '图纸版本号',
    dataIndex: 'drawingVersion'
  },
  {
    title: '操作',
    dataIndex: 'actions',
    fixed: 'right',
    scopedSlots: { customRender: 'actions' }
  }
]
export default {
  name: 'DialogModel',
  components: {
    DialogForm
  },
  data() {
    return {
      columnsHistory,
      downloading: false, // 下载loading
      rules: {
        modelClassifyId: [{ required: true, message: '请选择模型分类', trigger: 'change' }],
        modelTypeId: [{ required: true, message: '请选择模型类别', trigger: 'change' }],
        professionalTypeId: [{ required: true, message: '请选择专业分类', trigger: 'change' }],
        modelSourceId: [{ required: true, message: '请选择模型来源', trigger: 'change' }],
        floorLabelId: [{ required: true, message: '请选择楼层标签', trigger: 'change' }],
        detailDegreeId: [{ required: true, message: '请选择详细程度', trigger: 'change' }],
        modelName: [{ required: true, whitespace: true, message: '请输入模型名称', trigger: 'change' }],
        portfolioModelName: [{ required: true, whitespace: true, message: '请输入组合模型名称', trigger: 'change' }],
        fileList: [{ required: true, type: 'array', message: '请选择模型', trigger: 'change' }]
      },
      getBimModelDetail: {
        getDetail: getBimModelDetail
      } // 获取BIM模型详情
    }
  },
  props: {
    // 操作类型：0 上传模型；1 编辑；2 更新模型版本；3 历史版本；4 组合模型
    editModel: {
      type: [String, Number],
      default: () => 0
    },
    // 显隐控件
    visible: {
      type: Boolean,
      default: () => false
    },
    // 表单
    forms: {
      type: Object,
      default: () => null
    },
    // 刷新父组件列表
    refresh: Function,
    // 模型名
    modelName: {
      type: String,
      default: ''
    }
  },
  computed: {
    // 与父组件绑定visible
    dialogVisible: {
      get: function () {
        return this.visible
      },
      set: function (e) {
        this.$emit('update:visible', e)
      }
    },
    // 与父组件绑定forms
    form: {
      get: function () {
        return this.forms
      },
      set: function (e) {
        this.$emit('update:forms', e)
      }
    },
    // 表单列表
    formList() {
      let modelForm = [
        {
          keyName: 'projectName',
          type: 'BaseInput',
          label: '所属项目',
          span: 12,
          disabled: true
        },
        {
          keyName: 'fileList',
          slot: true,
          label: '选择模型',
          span: 24
        },
        {
          keyName: 'modelName',
          type: 'BaseInput',
          span: 12,
          label: '模型名称'
        },
        {
          keyName: 'modelVersion',
          type: 'BaseInput',
          span: 12,
          label: '版本',
          disabled: true
        },
        {
          keyName: 'modelClassifyId',
          viewName: 'modelClassifyName',
          span: 12,
          type: Selector,
          label: '模型分类',
          attrs: {
            customApi: getPageTypesLabel,
            customQuery: { param: { type: '38' } },
            dataValue: 'data.list'
          }
        },
        {
          keyName: 'versionExplain',
          type: 'BaseInput',
          disabled: this.editModel == 1,
          span: 12,
          label: '版本说明'
        },
        {
          keyName: 'modelTypeId',
          viewName: 'modelTypeName',
          span: 12,
          type: Selector,
          label: '模型类别',
          attrs: {
            customApi: getPageTypesLabel,
            customQuery: { param: { type: '33' } },
            dataValue: 'data.list'
          }
        },
        {
          keyName: 'modelIntroduce',
          type: 'BaseInput',
          span: 12,
          label: '模型介绍'
        },
        {
          keyName: 'professionalTypeId',
          viewName: 'professionalTypeName',
          type: Selector,
          label: '专业分类',
          span: 12,
          attrs: {
            customApi: getPageTypesLabel,
            customQuery: { param: { type: '34' } },
            dataValue: 'data.list'
          }
        },
        {
          keyName: 'detailDegreeId',
          viewName: 'detailDegreeName',
          type: Selector,
          label: '详细程度',
          span: 12,
          attrs: {
            customApi: getPageTypesLabel,
            customQuery: { param: { type: '37' } },
            dataValue: 'data.list'
          }
        },
        {
          keyName: 'floorLabelId',
          viewName: 'floorLabelName',
          type: Selector,
          span: 12,
          label: '楼层标签',
          attrs: {
            customApi: getPageTypesLabel,
            customQuery: { param: { type: '35' } },
            dataValue: 'data.list'
          }
        },
        {
          keyName: 'modelSourceId',
          viewName: 'modelSourceName',
          type: Selector,
          span: 12,
          label: '模型来源',
          attrs: {
            customApi: getPageTypesLabel,
            customQuery: { param: { type: '36' } },
            dataValue: 'data.list'
          }
        }
      ] // 模型上传表单
      const updateModel = [
        {
          keyName: 'projectName',
          type: 'BaseInput',
          label: '所属项目',
          span: 12,
          disabled: true
        },
        {
          keyName: 'fileList',
          slot: true,
          label: '选择模型',
          span: 24
        },
        {
          keyName: 'modelVersion',
          type: 'BaseInput',
          span: 12,
          label: '版本',
          disabled: true
        },
        {
          keyName: 'versionExplain',
          type: 'BaseInput',
          span: 12,
          label: '版本说明'
        }
      ]
      const combindModel = [
        {
          keyName: 'portfolioModelName',
          type: 'BaseInput',
          span: 24,
          label: '组合模型名称'
        }
      ]
      return [modelForm, modelForm, updateModel, [], combindModel][this.editModel]
    }
  },
  methods: {
    /**
     * @description: 渲染表单前回调
     * @param {Object} e：行对象
     */
    beforeInit(e) {
      if (this.editModel === 2) {
        let modelVersion = e.modelVersion?.split('.')
        e.modelVersion = modelVersion[0] + '.' + (Number(modelVersion[1]) + 1)
        e.modelId = e.id
      }
      e.fileList = [
        {
          uid: '1',
          status: 'done',
          name: e.modelFileName || '模型.zip'
        }
      ]
    },
    /**
     * @description: 删除模型历史版本
     * @param {Object} e：行对象
     */
    handleRemove(e) {
      this.$confirm({
        title: '提示',
        content: '确认删除该版本模型？',
        onOk: () => {
          return deleteBimModelVersion({
            id: e.id
          }).then((res) => {
            if (res.code === '0') {
              this.$message.success('删除成功')
              this.$refs.tableHistory.getData(null, true) // 刷新列表
            }
          })
        }
      })
    },
    /**
     * @description: 下载模型
     * @param {String} id：模型id
     */
    async handleDownload(record) {
      console.log(record, 'record')
      this.downloading = true
      const [err, res] = await downloadModel({ modelId: record.modelFileId, version: record.modelFileVersion })
      this.downloading = false
      if (!err) {
        const blob = new Blob([res])
        const filename =  record.modelFileName
        const downloadElement = document.createElement('a')
        const href = window.URL.createObjectURL(blob) // 创建下载的链接
        downloadElement.href = href
        downloadElement.download = filename // 获取文件名
        document.body.appendChild(downloadElement)
        downloadElement.click() //点击下载
        document.body.removeChild(downloadElement) //下载完成移除元素
        window.URL.revokeObjectURL(href) //释放blob对象
      }
    },
    /**
     * @description: 文件发生改变
     * @param {*} info：文件对象
     */
    handleUploadChanged(info) {
      if (!['application/zip', 'application/x-zip-compressed'].includes(info.file.type)) {
        this.$message.warning('只能上传zip格式！')
        return
      }
      const { fileList } = info
      console.log(info)
      this.form.modelFileName = info.file.name
      this.form.fileList = fileList
      if (fileList.length > 1) {
        this.form.fileList = [fileList.pop()]
      }
      // 触发表单校验
      this.$refs.dialogForm.$refs.ruleForm?.validateField('fileList')
    },
    /**
     * @description: 上传之前回调
     * @param {*} file：文件
     * @return {Boolean}
     */
    beforeUpload(file) {
      if (file.type !== 'application/zip') {
        // this.form.fileList = null
        return false
      }
      this.form.fileList = [file]
      return false
    },
    /**
     * @description: 打开模型
     * @param {Array} data：模型列表或者模型选中项
     */
    handleOpen(data) {
      let modelList = data.selectedRowsMap ? Array.from(data.selectedRowsMap, (item) => item[1])?.[0]?.map((i) => i.modelFileId) : data
      this.$router.push({
        path: '/bimIntegrate/model/modelPreview',
        query: {
          modelList: JSON.stringify(modelList)
        }
      })
      this.dialogVisible = false
    },
    /**
     * @description: 提交表单
     * @param {*} e：表单
     */
    async submitForm(e) {
      let form = this.$clone(e)
      const { fileList, modelFileId } = this.form
      const formData = new FormData()
      if (fileList?.length > 0 || this.editModel === 4) {
        // 处理上传模型参数
        fileList?.forEach((file) => {
          const fileName = form.modelFileName !== '' ? form.modelFileName : file.name.split('.')[0]
          formData.append('name', fileName)
          formData.append('modelFile', file.originFileObj)
          if (this.editMode === 1) {
            formData.append('id', modelFileId)
          }
        })
        // 区分是否需要更新模型版本(即是否需要上传模型文件)
        this.$refs.dialogForm.loading = true
        let result = [null, null]
        if (fileList?.[0]?.originFileObj) {
          if (this.editModel === 2) {
            result = await updateModel({ modelId: modelFileId }, formData)
          } else if (this.editModel === 0) {
            result = await uploadModel(formData)
          }
        } else {
          // 当操作是更新模型，提示模型未更新
          if (this.editModel === 2) {
            this.$message.warning('模型未更改，请重新上传模型！')
            this.$refs.dialogForm.loading = false
            return
          }
        }
        const [err, res] = result
        if (!err) {
          if (res?.data) {
            form.modelFileId = res.data?._id // 添加模型id
            form.modelFileVersion = res.data?.version // 添加模型id
            form.modelSize = (res.data?.modelFile?.fileSize / 1024 / 1024)?.toFixed(2) // 添加模型内存大小参数
          }
          form.fileList && delete form.fileList
          const api = [addBimModel, editBimModel, addBimModelVersion, null, addBimPortfolioModel][this.editModel]
          // 上传模型成功之后，将模型和项目绑定
          const ress = await api?.(form).catch(() => {
            this.$refs.dialogForm.loading = false
          })
          this.$refs.dialogForm.loading = false
          if (ress?.data?.code === '0') {
            this.$message.success('提交成功！')
            this.refresh()
            // 当操作为组合模型时
            if (this.editModel === 4) {
              // 刷新组合模型菜单
              this.$bus.$emit('refreshCompose')
              // 切换tab到组合模型菜单
              this.$emit('updateActiveKey')
            }
            this.dialogVisible = false
          }
        } else {
          // this.$message.error('更新模型失败！')
          this.$refs.dialogForm.loading = false
        }
      }
    },
    /**
     * @description: 模型版本历史列表分页查询接口
     * @param {*} params:分页参数
     * @return {Promise}
     */
    loadDataHistory(params) {
      let args = Object.assign(params, { param: { modelId: this.form?.id } })
      return getBimModelVersion(args).then((res) => {
        if (res.code === '0') {
          return { code: 200, data: res.data?.list, total: res.data?.total }
        }
      })
    }
  }
}
</script>